package net.qhzw.vip.qiyu.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.hutool.core.io.IORuntimeException;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import net.qhzw.vip.qiyu.dto.InvoiceExcelDto;
import net.qhzw.vip.qiyu.dto.OrderItemExcelDto;
import net.qhzw.vip.qiyu.dto.SoldOrderExcelDto;
import net.qhzw.vip.qiyu.entity.*;
import net.qhzw.vip.qiyu.enums.OrderStatus;
import net.qhzw.vip.qiyu.param.DeliveryOrderParam;
import net.qhzw.vip.qiyu.param.OrderParam;
import net.qhzw.vip.qiyu.result.JsonResult;
import net.qhzw.vip.qiyu.service.*;
import net.qhzw.vip.qiyu.util.Arith;
import net.qhzw.vip.qiyu.util.PageParam;
import net.qhzw.vip.qiyu.util.SecurityUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/order/order")
@Api(tags = "订单接口")
@Slf4j
public class OrderAdminController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private UserAddrOrderService userAddrOrderService;

    @Autowired
    private ProductService productService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private DeliveryManService deliveryManService;

    @Autowired
    private DeliveryService deliveryService;


    @Autowired
    private UserAddrOrderService userAddrService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private LogisticsService logisticsService;

    @Autowired
    private AdminUserService adminUserService;

    /**
     * 分页获取
     */
    @GetMapping("/page")
    public JsonResult<IPage<Order>> page(OrderParam orderParam, PageParam<Order> page) {
        Long shopId = adminUserService.getLoginUser(SecurityUtils.getUserId()).getShopId();
        orderParam.setShopId(shopId);
        IPage<Order> orderIPage = orderService.pageOrdersDetialByOrderParam(page, orderParam);
        return JsonResult.ok(orderIPage);
    }


    /**
     * 获取信息
     */
    @GetMapping("/orderInfo/{orderNumber}")
    public JsonResult<Order> info(@PathVariable("orderNumber") String orderNumber) {
        //Long shopId = SecurityUtils.getSysUser().getShopId();
        Order order = orderService.getOrderByOrderNumber(orderNumber);
        order.setTotal(Arith.sub(order.getActualTotal(), order.getDeliveryPrice()));
        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(orderNumber);
        for (OrderItem orderItem : orderItems) {
            orderItem.setSku(skuService.getSkuBySkuId(orderItem.getSkuId()));
        }
        order.setOrderItems(orderItems);
        Long deliveryId = order.getDeliveryId(); //自提点id
        DeliveryMan deliveryMan = deliveryManService.info(deliveryId);
        //UserAddrOrder userAddrOrder = userAddrOrderService.getById(order.getAddrOrderId());
//        order.setUserAddrOrder(userAddrOrder);
        order.setDeliveryMan(deliveryMan);

        return JsonResult.ok(order);
    }

    /**
     * 发货
     */
    @PutMapping("/delivery")
    public JsonResult delivery(@RequestBody DeliveryOrderParam deliveryOrderParam) {
        Long shopId = SecurityUtils.getLoginUser().getShopId();
        Order order = orderService.getOrderByOrderNumber(deliveryOrderParam.getOrderNumber());
        Order orderParam = new Order();
        orderParam.setOrderId(order.getOrderId());
        orderParam.setDvyId(shopId);
        orderParam.setDvyTime(new Date());
        orderParam.setStatus(OrderStatus.CONSIGNMENT.value());
        orderParam.setUserId(order.getUserId());
        String dvyFlowId = "";

//        if (0 == order.getShippingType().intValue()) {
//            DeliveryMan deliveryMan = deliveryManService.getById(deliveryOrderParam.getDvyId());
//            if (deliveryMan != null) {
//                dvyFlowId = deliveryMan.getRealName() + " " + deliveryMan.getMobile();
//            }
//        } else {
//            dvyFlowId = deliveryOrderParam.getDvyFlowId();
//            Long dvyId = deliveryOrderParam.getDvyId();
//            Delivery delivery = deliveryService.getById(dvyId);
//            if (delivery != null) {
//                //顺丰请输入单号 : 收件人或寄件人手机号后四位 123456789:1234
//                if ("SFEXPRESS".equals(delivery.getDvyType())) {
//                    UserAddrOrder userAddr = userAddrService.getById(order.getAddrOrderId());
//                    if (userAddr != null) {
//                        String tailNumber = userAddr.getMobile().substring(userAddr.getMobile().length() - 4, userAddr.getMobile().length());
//                        dvyFlowId = dvyFlowId + ":" + tailNumber;
//                    }
//                }
//                orderParam.setDvyType(delivery.getDvyName());
//            }
//        }
        updateLogistics(deliveryOrderParam.getOrderNumber());

        orderParam.setDvyFlowId(dvyFlowId);
        orderService.delivery(orderParam);
        List<OrderItem> orderItems = orderItemService.getOrderItemsByOrderNumber(deliveryOrderParam.getOrderNumber());
        for (OrderItem orderItem : orderItems) {
            productService.removeProductCacheByProdId(orderItem.getProdId());
            skuService.removeSkuCacheBySkuId(orderItem.getSkuId(), orderItem.getProdId());
        }
        rabbitTemplate.convertAndSend("RECEIPT_EXCHANGE", "receipt", deliveryOrderParam.getOrderNumber());
        return JsonResult.ok();
    }


    /**
     * 跟新物流
     *
     * @param orderNumber
     */
    private void updateLogistics(String orderNumber) {
        Logistics logistics = new Logistics();
        logistics.setOrderNumber(orderNumber);
        logistics.setDetails("已发货");
        logisticsService.save(logistics);
    }


    /**
     * 打印待发货的订单表
     *
     * @param consignmentName   发件人姓名
     * @param consignmentMobile 发货人手机号
     * @param consignmentAddr   发货地址
     */
    @GetMapping("/waitingConsignmentExcel")
    public void waitingConsignmentExcel(String orderNumber, Integer shippingType, Integer status, Integer isPayed,
                                        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
                                        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime,
                                        String consignmentName, String consignmentMobile,
                                        String consignmentAddr, HttpServletResponse response) {
        //order.setStatus(2);
        List<Order> orders = orderService.listOrdersDetialByOrder(orderNumber, shippingType, status, isPayed, startTime, endTime);
        List<InvoiceExcelDto> OrderExcelDtos = new ArrayList<>(orders.size());
        for (Order dbOrder : orders) {
            UserAddrOrder addr = dbOrder.getUserAddrOrder();
            String addrInfo = addr.getProvince() + addr.getCity() + addr.getArea() + addr.getAddr();
            List<OrderItem> orderItems = dbOrder.getOrderItems();
            for (OrderItem orderItem : orderItems) {
                InvoiceExcelDto orderExcelDto = new InvoiceExcelDto();
                orderExcelDto.setOrderNumber(dbOrder.getOrderNumber());
                orderExcelDto.setReceiver(addr.getReceiver());
                orderExcelDto.setMobile(addr.getMobile());
                orderExcelDto.setAddrInfo(addrInfo);
                orderExcelDto.setProdName(orderItem.getProdName());
                orderExcelDto.setProdCount(orderItem.getProdCount());
                orderExcelDto.setConsignmentName(consignmentName);
                orderExcelDto.setConsignmentMobile(consignmentMobile);
                orderExcelDto.setConsignmentAddr(consignmentAddr);
                orderExcelDto.setShippingType(dbOrder.getShippingType());
                orderExcelDto.setRemarks(dbOrder.getRemarks());
                OrderExcelDtos.add(orderExcelDto);
            }
        }
        //表单导出
        excel(response, "待发货单", "", InvoiceExcelDto.class, OrderExcelDtos);
    }

    /**
     * 已销售订单
     *
     */
    @GetMapping("/soldExcel")
    public void soldExcel(String orderNumber, Integer shippingType, Integer status, Integer isPayed,
                          @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
                          @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime,
                          HttpServletResponse response) {

        //order.setIsPayed(1);
        List<Order> orders = orderService.listOrdersDetialByOrder(orderNumber, shippingType, status, isPayed, startTime, endTime);
        List<SoldOrderExcelDto> soldOrderExcelDtos = new ArrayList<>();
        // 待发货
        String[] hearder = {"订单编号", "下单时间", "收件人", "手机", "收货地址", "商品名称", "数量", "订单应付", "订单运费", "订单实付"};

        for (Order dbOrder : orders) {
            UserAddrOrder addr = dbOrder.getUserAddrOrder();
            String addrInfo = addr.getProvince() + addr.getCity() + addr.getArea() + addr.getAddr();
            List<OrderItem> orderItems = dbOrder.getOrderItems();
            SoldOrderExcelDto soldOrderExcelDto = new SoldOrderExcelDto();
            soldOrderExcelDto.setOrderNumber(dbOrder.getOrderNumber());
            soldOrderExcelDto.setCreateTime(dbOrder.getCreateTime());
            soldOrderExcelDto.setReceiver(addr.getReceiver());
            soldOrderExcelDto.setMobile(addr.getMobile());
            soldOrderExcelDto.setAddrInfo(addrInfo);
//            List<String> prodNames = new ArrayList<>();
//            List<Integer> prodCounts = new ArrayList<>();
            List<OrderItemExcelDto> orderItemExcelDtos = new ArrayList<>();
            for (OrderItem orderItem : orderItems) {
                String prodName = orderItem.getProdName();
                Integer prodCount = orderItem.getProdCount();
//                prodNames.add(prodName);
//                prodCounts.add(prodCount);
                orderItemExcelDtos.add(new OrderItemExcelDto(prodName, prodCount));
            }
//            soldOrderExcelDto.setProdName(prodNames);
//            soldOrderExcelDto.setProdCount(prodCounts);
            soldOrderExcelDto.setOrderItemExcelDto(orderItemExcelDtos);
            // 订单应付
            soldOrderExcelDto.setTotal(dbOrder.getTotal());
            // 订单运费
            soldOrderExcelDto.setFreightAmount(dbOrder.getFreightAmount());
            // 订单实付
            soldOrderExcelDto.setActualTotal(dbOrder.getActualTotal());
            soldOrderExcelDtos.add(soldOrderExcelDto);
        }
        //表单导出
        excel(response, "已销售订单", "", SoldOrderExcelDto.class, soldOrderExcelDtos);
    }

    /***
     * 表单导出
     * @param response
     * @param title
     * @param sheetName
     * @param pojoClass
     * @param dataSet
     */
    private void excel(HttpServletResponse response, String title, String sheetName, Class<?> pojoClass, Collection<?> dataSet) {
        Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams(title, sheetName), pojoClass, dataSet);
        ServletOutputStream os = null;
        try {
            response.setHeader("content-disposition", "attachment;fileName=" + URLEncoder.encode(title + ".xls", "UTF-8"));
            os = response.getOutputStream();
            workbook.write(os);
            os.close();
            workbook.close();
        } catch (IOException e) {
            log.error("【导出" + title + ",错误】{}", JSON.toJSONString(e, true));
        } finally {
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    /*public void soldExcel(Order order, @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date startTime,
                          @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date endTime,
                          HttpServletResponse response) {
        Long shopId = SecurityUtils.getSysUser().getShopId();
        order.setShopId(shopId);
        order.setIsPayed(1);
        List<Order> orders = orderService.listOrdersDetialByOrder(order, startTime, endTime);
        //通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter();
        // 待发货
        String[] hearder = {"订单编号", "下单时间", "收件人", "手机", "收货地址", "商品名称", "数量", "订单应付", "订单运费", "订单实付"};
        Sheet sheet = writer.getSheet();
        sheet.setColumnWidth(0, 20 * 256);
        sheet.setColumnWidth(1, 20 * 256);
        sheet.setColumnWidth(3, 20 * 256);
        sheet.setColumnWidth(4, 60 * 256);
        sheet.setColumnWidth(5, 60 * 256);
        writer.merge(hearder.length - 1, "销售信息整理");
        writer.writeRow(Arrays.asList(hearder));
        int row = 1;
        for (Order dbOrder : orders) {
            UserAddrOrder addr = dbOrder.getUserAddrOrder();
            String addrInfo = addr.getProvince() + addr.getCity() + addr.getArea() + addr.getAddr();
            List<OrderItem> orderItems = dbOrder.getOrderItems();
            int firstRow = row + 1;
            int lastRow = row + orderItems.size();
            int col = -1;
            // 订单编号
            mergeIfNeed(writer, firstRow, lastRow, ++col, col, dbOrder.getOrderNumber());
            // 下单时间
            mergeIfNeed(writer, firstRow, lastRow, ++col, col, dbOrder.getCreateTime());
            // 收件人
            mergeIfNeed(writer, firstRow, lastRow, ++col, col, addr.getReceiver());
            // "手机"
            mergeIfNeed(writer, firstRow, lastRow, ++col, col, addr.getMobile());
            // "收货地址"
            mergeIfNeed(writer, firstRow, lastRow, ++col, col, addrInfo);
            int prodNameCol = ++col;
            int prodCountCol = ++col;
            for (OrderItem orderItem : orderItems) {
                row++;
                // 商品名称
                writer.writeCellValue(prodNameCol, row, orderItem.getProdName());
                // 数量
                writer.writeCellValue(prodCountCol, row, orderItem.getProdCount());
            }
            // 订单应付
            mergeIfNeed(writer, firstRow, lastRow, ++col, col, dbOrder.getTotal());
            // 订单运费
            mergeIfNeed(writer, firstRow, lastRow, ++col, col, dbOrder.getFreightAmount());
            // 订单实付
            mergeIfNeed(writer, firstRow, lastRow, ++col, col, dbOrder.getActualTotal());
        }
        writeExcel(response, writer);
    }*/

    private void writeExcel(HttpServletResponse response, ExcelWriter writer) {
        //response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=1.xls");
        ServletOutputStream servletOutputStream = null;
        try {
            servletOutputStream = response.getOutputStream();
            writer.flush(servletOutputStream);
            servletOutputStream.flush();
        } catch (IORuntimeException | IOException e) {
            e.printStackTrace();
        } finally {
            writer.close();
            try {
                if (servletOutputStream != null) {
                    servletOutputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 如果需要合并的话，就合并
     */
    private void mergeIfNeed(ExcelWriter writer, int firstRow, int lastRow, int firstColumn, int lastColumn, Object content) {
        if (lastRow - firstRow > 0 || lastColumn - firstColumn > 0) {
            writer.merge(firstRow, lastRow, firstColumn, lastColumn, content, false);
        } else {
            writer.writeCellValue(firstColumn, firstRow, content);
        }
    }


}
